/**
  ****************************************************************************************************
  * @file    main.c
  * @author  FMSH Application Team
  * @brief   Header file of FL Module
  ****************************************************************************************************
  * @attention
  *
  * Copyright (c) [2021] [Fudan Microelectronics]
  * THIS SOFTWARE is licensed under Mulan PSL v2.
  * can use this software according to the terms and conditions of the Mulan PSL v2.
  * You may obtain a copy of Mulan PSL v2 at:
  *          http://license.coscl.org.cn/MulanPSL2
  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  * See the Mulan PSL v2 for more details.
  *
  ****************************************************************************************************
  */

#include "main.h"
#include "fm33_assert.h"
#include "MFRC522.h"
#include "basetime.h"


/**
* Chip Series: FM33LG0xx;
* FL Version: v2.3;
* Project Name: rc522;
* Project Version: v2.3.0.0;
* Project ID: 1930827742207062017;
* Create Date: 2025-06-06;
*/



void dump_byte_array(uint8_t *buffer, uint8_t bufferSize)
{
    for (size_t i = 0; i < bufferSize; i++)
    {
        printf(buffer[i]<0x10?" 0":" ");
        printf("%X",buffer[i]);
    }

}

MIFARE_Key key;

int main(void)
{

    /* Initialize FL Driver Library */
    FL_Init();
    DelayTimeBase();
    BaseTime();
    /* Configure the system clock */
    MF_Clock_Init();

    /* Initialize all configured peripherals */
    MF_Config_Init();

    PCD_Init();// Init MFRC522 card


    // Prepare the key (used both as key A and as key B)
    // using FFFFFFFFFFFFh which is the default at chip delivery from the factory
    for (size_t i = 0; i < 6; i++)
    {
        key.keyByte[i] = 0xFF;
    }

    printf("Scan a MIFARE Classic PICC to demonstrate read and write.\r\n");
    printf("Using key (for A and B):");
    dump_byte_array(key.keyByte, MF_KEY_SIZE);
    printf("\r\n");
    printf("BEWARE: Data will be written to the PICC, in sector #1\r\n");

    while (1)
    {
        // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
        if (!PICC_IsNewCardPresent())
        {
            continue;
        }
        // Select one of the cards
        if (!PICC_ReadCardSerial())
        {
            continue;;
        }
        printf("Card UID:");
        dump_byte_array(uid.uidByte, uid.size);
        printf("\r\n");
        printf("PICC type: ");
        PICC_Type piccType = PICC_GetType(uid.sak);
        printf("%s\r\n", PICC_GetTypeName(piccType));

        if (   piccType != PICC_TYPE_MIFARE_MINI
            && piccType != PICC_TYPE_MIFARE_1K
            && piccType != PICC_TYPE_MIFARE_4K)
        {
            printf("This sample only prints details for MIFARE Classic cards.\r\n");
            continue;
        }

        // In this sample we use the second sector,
        // that is: sector #1, covering block #4 up to and including block #7
        uint8_t sector = 1;
        uint8_t blockAddr = 4;
        uint8_t dataBlock[] = {
            0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
            0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
            0x09, 0x0a, 0xff, 0x0b, //  9, 10, 255, 11,
            0x0c, 0x0d, 0x0e, 0x0f  // 12, 13, 14, 15
        };
        uint8_t trailerBlock = 7;
        StatusCode status;
        uint8_t buffer[18];
        uint8_t size = sizeof(buffer);


        // Authenticate using key A
        printf("Authenticating using key A...\r\n");
        status = PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &uid);
        if (status != STATUS_OK)
        {
            printf("PCD_Authenticate() failed: %s\r\n", GetStatusCodeName(status));
            continue;
        }

        // Show the whole sector as it currently is
        printf("Current data in sector:\r\n");
        PICC_DumpMifareClassicSectorToSerial(&uid, &key,sector);
        printf("\r\n");

        // Read data form the block
        printf("Reading data from block %d...\r\n", blockAddr);
        status = MIFARE_Read(blockAddr, buffer, &size);
        if (status!= STATUS_OK)
        {
            printf("MIFARE_Read() failed: %s\r\n", GetStatusCodeName(status));
            continue;
        }
        printf("Data in block %d: ", blockAddr);
        dump_byte_array(buffer, 16);
        printf("\r\n");
        printf("\r\n");

        // Authenticate using key B
        printf("Authenticating using key B...\r\n");
        status = PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &uid);
        if (status!= STATUS_OK)
        {
            printf("PCD_Authenticate() failed: %s\r\n", GetStatusCodeName(status));
            continue;
        }
        printf("\r\n");

        // Write data to the block
        printf("Writing data into block %d...\r\n", blockAddr);
        dump_byte_array(dataBlock,16);
        printf("\r\n");
        status = MIFARE_Write(blockAddr, dataBlock, 16);
        if (status!= STATUS_OK)
        {
            printf("MIFARE_Write() failed: %s\r\n", GetStatusCodeName(status));
            continue;
        }
        printf("\r\n");

        // Read data form the block again (again, should now be what we have written)
        printf("Reading data from block %d...\r\n", blockAddr);
        status = MIFARE_Read(blockAddr, buffer, &size);
        if (status!= STATUS_OK)
        {
            printf("MIFARE_Read() failed: %s\r\n", GetStatusCodeName(status));
            continue;
        }
        printf("Data in block %d: ", blockAddr);
        dump_byte_array(buffer, 16);
        printf("\r\n");

        // Check that data in block is what we have written
        // by counting the number of bytes that are equal
        printf("Checking results...");
        uint8_t count = 0;
        for (size_t i = 0; i < 16; i++)
        {
            if (buffer[i]== dataBlock[i]) count++;
        }
        printf("Number of bytes that match = %d", count);
        if (count ==16)
        {
            printf("Success :-)\r\n");
        }
        else
        {
            printf("Failure, no match :-(\r\n");
            printf("  perhaps the write didn't work properly...\r\n");
        }
        printf("\r\n");

        // Dump the sector data
        printf("Current data in sector:\r\n");
        PICC_DumpMifareClassicSectorToSerial(&uid, &key,sector);
        printf("\r\n") ;

        // Halt PICC
        PICC_HaltA();
        // Stop encryption on PCD
        PCD_StopCrypto1();
    }
}
